package com.fourtails.usuariolecturista.jobs; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.util.Log; import com.fourtails.usuariolecturista.MainActivity; import com.fourtails.usuariolecturista.ottoEvents.UploadImageEvent; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.ByteArrayContent; import com.google.api.client.http.GenericUrl; import com.google.api.client.http.HttpContent; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpRequestFactory; import com.google.api.client.http.HttpResponse; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.storage.StorageScopes; import com.orhanobut.logger.Logger; import com.path.android.jobqueue.Job; import com.path.android.jobqueue.Params; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Collections; import java.util.UUID; /** * call to upload a picture from the camera to Google Cloud Storage * TODO: SECURITY PROBLEM remove the key from assets, find a way to do it */ public class UploadFileToGCSJob extends Job { boolean responseOk = false; boolean retry = true; Context mContext; String mBucketName; Bitmap mImageBitmap; /** * Global instance of the JSON factory. */ private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); public UploadFileToGCSJob(Bitmap image, Context context, String bucketName) { super(new Params(Priority.LOW).requireNetwork().groupBy("upload-file")); mImageBitmap = image; mContext = context; mBucketName = bucketName; } @Override public void onAdded() { } @Override public void onRun() throws Throwable { // convert key into class File. from inputStream to file. in an aux class. File file = createFileFromInputStream(); NetHttpTransport httpTransport = new NetHttpTransport(); String emailAddress = "382197999605-nc5h44q7v54mgn915eqvtd71is4r46jg@developer.gserviceaccount.com"; // Google credentials GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport) .setJsonFactory(JSON_FACTORY) .setServiceAccountId(emailAddress) .setServiceAccountScopes(Collections.singleton(StorageScopes.DEVSTORAGE_FULL_CONTROL)) .setServiceAccountPrivateKeyFromP12File(file) .build(); String imageName = generateIdentifierForImage(); String URI = "https://storage.googleapis.com/" + mBucketName + "/" + imageName + ".jpg"; HttpRequestFactory requestFactory = httpTransport.createRequestFactory(credential); GenericUrl url = new GenericUrl(URI); byte[] mImageBytes = bitmapToByteArray(mImageBitmap); HttpContent contentSend = new ByteArrayContent("image/jpeg", mImageBytes); HttpRequest putRequest = requestFactory.buildPutRequest(url, contentSend); HttpResponse response = putRequest.execute(); if (response.isSuccessStatusCode()) { Logger.i(response.getStatusMessage() + "Uploading image"); responseOk = true; MainActivity.bus.post(new UploadImageEvent(UploadImageEvent.Type.COMPLETED, 1, imageName)); } } /** * Bitmap to array method * * @param bitmap bitmap to convert * @return byte array */ public static byte[] bitmapToByteArray(Bitmap bitmap) { Log.d("IMAGE", "Compressing bmp"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); Log.d("IMAGE", "Finished compressing bmp"); return baos.toByteArray(); } /** * Creates a temporary file that stores the .p12 GCS authentication services * TODO: security concern about the file being on assets. * * @return a p12 file */ private File createFileFromInputStream() { File file = null; try { // we take the key and put it in a temporary file AssetManager am = mContext.getAssets(); InputStream inputStream = am.open("privatekey.p12"); //you should not put the key in assets in prod version. file = File.createTempFile("tempKeyFile", "p12"); OutputStream outputStream = new FileOutputStream(file); byte buffer[] = new byte[1024]; int length = 0; while ((length = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, length); } outputStream.close(); inputStream.close(); } catch (IOException e) { Logger.e("Can't create a file from input stream"); } return file; } /** * Generates a random Identifier for the image * * @return random id */ public String generateIdentifierForImage() { UUID id = UUID.randomUUID(); return id.toString(); } @Override protected void onCancel() { Logger.d("Error in user profile image uploading"); MainActivity.bus.post(new UploadImageEvent(UploadImageEvent.Type.COMPLETED, 99, null)); } @Override protected boolean shouldReRunOnThrowable(Throwable throwable) { return false; } }